package com.bocloud.controller.user;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.bocloud.dto.ApiDto;
import com.bocloud.inter.service.table.IModuleService;
import com.bocloud.kong.KongConfig;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bocloud.dto.LoginInfoDto;
import com.bocloud.dto.SearchDto;
import com.bocloud.enumeration.MonitorType;
import com.bocloud.framework.JsonResult;
import com.bocloud.framework.MyException;
import com.bocloud.framework.auth.AuthPassport;
import com.bocloud.framework.base.BaseController;
import com.bocloud.inter.service.table.IErrorService;
import com.bocloud.inter.service.table.IInterfaceService;
import com.bocloud.inter.service.tool.ICacheService;
import com.bocloud.inter.service.tool.ISearchService;
import com.bocloud.kong.model.Api;
import com.bocloud.kong.service.ApiService;
import com.bocloud.model.Error;
import com.bocloud.model.Interface;
import com.bocloud.model.Module;
import com.bocloud.model.Result;
import com.bocloud.springbeans.Config;
import com.bocloud.utils.Const;
import com.bocloud.utils.DateFormartUtil;
import com.bocloud.utils.MyString;
import com.bocloud.utils.Page;
import com.bocloud.utils.Tools;
import com.wordnik.swagger.annotations.ApiOperation;

import net.sf.json.JSONArray;

@Controller
@RequestMapping("/user/interface")
public class InterfaceController extends BaseController<Interface> {

	@Autowired
	private IInterfaceService interfaceService;
	@Autowired
	private IErrorService errorService;
	@Autowired
	private ICacheService cacheService;
	@Autowired
	private ISearchService luceneService;
	@Autowired
	private ApiService apiService;
	@Autowired
	private Config config;
	@Autowired
	private KongConfig kongConfig;
	@Autowired
	private IModuleService moduleService;

	@RequestMapping("/list.do")
	@ResponseBody
	@AuthPassport
	public JsonResult list(@ModelAttribute Interface interFace, @RequestParam(defaultValue = "1") Integer currentPage)
			throws MyException {
		Page page = new Page(15);
		page.setCurrentPage(currentPage);
		hasPermission(cacheService.getProject(interFace.getProjectId()), view);

		List<Interface> interfaces = interfaceService.findByMap(
				Tools.getMap("moduleId", interFace.getModuleId(), "interfaceName|like", interFace.getInterfaceName(),
						"fullUrl|like", interFace.getUrl()),
				" new Interface(id,moduleId,interfaceName,version,createTime,updateBy,updateTime,remark,sequence,template,kongApiUrl,kongApiId)",
				page, null);

		if(interfaces!=null){
			for(Interface tmp:interfaces){
				if(!MyString.isEmpty(tmp.getKongApiUrl())) {
					tmp.setKongApiFullUrl(kongConfig.getKongHttpAddress() + tmp.getKongApiUrl());
				}
			}

		}

		return new JsonResult(1, interfaces, page,
				Tools.getMap("crumbs",
						Tools.getCrumbs("接口列表:" + cacheService.getModuleName(interFace.getModuleId()), "void"),
						"module", cacheService.getModule(interFace.getModuleId())));

	}

	@RequestMapping("/detail.do")
	@ResponseBody
	public JsonResult detail(@RequestParam String id, String moduleId) throws MyException {
		Interface model;
		if (!id.equals(Const.NULL_ID)) {
			model = interfaceService.get(id);
			hasPermission(cacheService.getProject(model.getProjectId()), view);
		} else {
			model = new Interface();
			model.setModuleId(moduleId);
			Module module = cacheService.getModule(moduleId);
			if (!MyString.isEmpty(module.getTemplateId())) {
				Interface template = interfaceService.get(module.getTemplateId());
				// 根据模板初始化接口
				if (template != null) {
					model.setHeader(template.getHeader());
					model.setParam(template.getParam());
					model.setMethod(template.getMethod());
					model.setVersion(template.getVersion());
					model.setParamRemark(template.getParamRemark());
					model.setResponseParam(template.getResponseParam());
					model.setErrorList(template.getErrorList());
					model.setErrors(template.getErrors());
					model.setFalseExam(template.getFalseExam());
					model.setTrueExam(template.getTrueExam());
					model.setStatus(template.getStatus());
				}
			}

		}
		return new JsonResult(1, model);
	}

	/**
	 * 加载Kong api 信息
	 */
	@RequestMapping("/up.do")
	@ResponseBody
	public JsonResult up(@RequestParam String id) throws MyException {
		Interface model = null;
		Api api = null;
		ApiDto apiDto = new ApiDto();
		if (!id.equals(Const.NULL_ID)) {
			model = interfaceService.get(id);
			if(!MyString.isEmpty(model.getKongApiId())) {
				api = apiService.query(model.getKongApiId());
			}
			Module module = cacheService.getModule(model.getModuleId());

			if (api == null || !MyString.isEmpty(api.getErrorMessage())) {
				api = new Api();
				api.setName(model.getId());
				if (module.getUrl().endsWith("/"))
					module.setUrl(module.getUrl().substring(0, module.getUrl().length() - 1));
				api.setUpstream_url(module.getUrl()+""+ model.getUrl());
			}

			BeanUtils.copyProperties(api,apiDto);
			apiDto.setModuleName(module.getName());
			apiDto.setProjectName(module.getProjectName());
			apiDto.setInterfaceName(model.getInterfaceName());
		} else {
			return new JsonResult(0, null, "000099", "模块ID为空");
		}

		return new JsonResult(1, apiDto);
	}

    /**
     * 下线网关api
     *
     * */
    @RequestMapping("/downApi.do")
    @ResponseBody
    public JsonResult downApi(@RequestParam String id) throws Exception {
        // 系统数据，不允许删除
        Interface model = interfaceService.get(id);
        if (model != null) {
            apiService.delete(model.getKongApiId());

            model.setKongApiUrl(null);
            model.setKongApiId(null);
            interfaceService.update(model);
            luceneService.update(model.toSearchDto(cacheService));

        }else{
            return new JsonResult(0, null, "000099", "对应接口不存在【" + id + "】");
        }
        return new JsonResult(1, null);
    }

	/**
	 * 进行模块上线操作
	 */
	@RequestMapping("/upAddOrUpdate.do")
	@ResponseBody
	public JsonResult upAddOrUpdate(@ModelAttribute ApiDto api) throws Exception {

		Interface model = interfaceService.get(api.getName());

		if (model == null) {
			return new JsonResult(0, null, "000099", "对应接口不存在【" + api.getInterfaceName() + "】");
		}

		if (MyString.isEmpty(model.getUrl())) {
			return new JsonResult(0, null, "000099", "接口【" + api.getInterfaceName() + "】的URL不能为空");
		}

		if (!api.getUpstream_url().toLowerCase().startsWith("http://")
				&& !api.getUpstream_url().toLowerCase().startsWith("https://")) {
			return new JsonResult(0, null, "000099", "接口【" + api.getInterfaceName() + "】的URL必须以http://或https://开头");
		}

		Api newApi = new Api();

		BeanUtils.copyProperties(api,newApi);
		newApi.setUris(new String[]{"/" + model.getModuleName() + model.getUrl()});

		if(MyString.isEmpty(model.getKongApiId())){
			newApi.setId(null);
		}else{
			newApi.setId(model.getKongApiId());
		}

		Result result = apiService.save(newApi);

		if (!result.isSuccess()) {
			return new JsonResult(0, null, "000099", result.getMessage());
		}else{
			model.setKongApiId(((Api)result.getData()).getId());
			model.setKongApiUrl(newApi.getUris()[0]);
			interfaceService.update(model);
			luceneService.update(model.toSearchDto(cacheService));

		}

		return new JsonResult(1, api);
	}


	/**
	 * @param interFace
	 * @return
	 * @throws MyException
	 * @throws IOException
	 */
	@RequestMapping("/copy.do")
	@ResponseBody
	public JsonResult copy(@ModelAttribute Interface interFace) throws MyException, IOException {
		// 判断是否拥有该模块的权限
		hasPermission(cacheService.getProject(interFace.getProjectId()), addInter);
		if (!config.isCanRepeatUrl() && interfaceService.getCount(Tools.getMap("moduleId", interFace.getModuleId(),
				"fullUrl", interFace.getModuleUrl() + interFace.getUrl())) > 0) {
			throw new MyException("000004");
		}
		interFace.setId(null);
		interFace.setFullUrl(interFace.getModuleUrl() + interFace.getUrl());
		interfaceService.save(interFace);
		luceneService.add(interFace.toSearchDto(cacheService));
		return new JsonResult(1, interFace);
	}

	/**
	 * 根据参数生成请求示例
	 * 
	 * @param interFace
	 * @return
	 */
	@RequestMapping("/getRequestExam.do")
	@ResponseBody
	@AuthPassport
	public JsonResult getRequestExam(@ModelAttribute Interface interFace) {
		interfaceService.getInterFaceRequestExam(interFace);
		return new JsonResult(1, interFace);
	}

	@RequestMapping("/addOrUpdate.do")
	@ResponseBody
	@AuthPassport
	@ApiOperation(value = "api增加和更新接口", response = JsonResult.class, notes = "interface addOrUpdate")
	public JsonResult addOrUpdate(@ModelAttribute Interface interFace) throws IOException, MyException {
		if (MyString.isEmpty(interFace.getUrl()))
			return new JsonResult(new MyException("000005"));
		interFace.setUrl(interFace.getUrl().trim());
		if (!interFace.getUrl().startsWith("/"))
			interFace.setUrl("/" + interFace.getUrl());

		/**
		 * 根据选着的错误码id，组装json字符串
		 */
		String errorIds = interFace.getErrorList();
		if (errorIds != null && !errorIds.equals("")) {
			List<Error> errors = errorService.findByMap(
					Tools.getMap("errorCode|in", Tools.getIdsFromField(errorIds), "moduleId", interFace.getProjectId()),
					null, null);
			interFace.setErrors(JSONArray.fromObject(errors).toString());
		} else {
			interFace.setErrors("[]");
		}

		LoginInfoDto user = (LoginInfoDto) Tools.getUser();
		interFace.setUpdateBy("userName：" + user.getUserName() + " | trueName：" + user.getTrueName());
		interFace.setUpdateTime(DateFormartUtil.getDateByFormat(DateFormartUtil.YYYY_MM_DD_HH_mm));

		// 请求示例为空，则自动添加
		if (MyString.isEmpty(interFace.getRequestExam())) {
			interfaceService.getInterFaceRequestExam(interFace);
		}

		// 检查邮件格式是否正确
		if (interFace.getMonitorType() != MonitorType.No.getValue()) {
			if (!MyString.isEmpty(interFace.getMonitorEmails())) {
				for (String email : interFace.getMonitorEmails().split(";")) {
					if (!Tools.checkEmail(email)) {
						throw new MyException("000032");
					}
				}
			} else {
				throw new MyException("000032");
			}
		}
		boolean isAdd = MyString.isEmpty(interFace.getId());
		if (!isAdd) {
			interFace.setModuleId(interfaceService.get(interFace.getId()).getModuleId());
			// 判断是否有修改模块的权限
			hasPermission(cacheService.getProject(interFace.getProjectId()), modInter);

			// 同一模块下不允许 url 重复
			if (!config.isCanRepeatUrl() && interfaceService.getCount(Tools.getMap("moduleId", interFace.getModuleId(),
					"fullUrl", interFace.getModuleUrl() + interFace.getUrl(), "id|!=", interFace.getId())) > 0) {
				throw new MyException("000004");
			}

			interFace.setFullUrl(interFace.getModuleUrl() + interFace.getUrl());
			interfaceService.update(interFace, "接口", "");
			if (interFace.getId().equals(interFace.getProjectId())) {
				throw new MyException("000027");
			}
			luceneService.update(interFace.toSearchDto(cacheService));
		} else {
			hasPermission(cacheService.getProject(interFace.getProjectId()), addInter);
			if (!config.isCanRepeatUrl() && interfaceService
					.getCount(Tools.getMap("fullUrl", interFace.getModuleUrl() + interFace.getUrl())) > 0) {
				return new JsonResult(new MyException("000004"));
			}

			interFace.setChannel(
					config.getDomain() + "/" + Const.APP + "/" + interFace.getModuleName() + "/" + interFace.getUrl());
			interFace.setFullUrl(interFace.getModuleUrl() + interFace.getUrl());
			interfaceService.save(interFace);
			luceneService.add(interFace.toSearchDto(cacheService));
		}
		return new JsonResult(1, interFace);
	}

	@RequestMapping("/delete.do")
	@ResponseBody
	public JsonResult delete(@ModelAttribute Interface interFace) throws MyException, IOException {
		interFace = interfaceService.get(interFace.getId());
		hasPermission(cacheService.getProject(interFace.getProjectId()), delInter);
		interfaceService.delete(interFace, "接口", "");
		luceneService.delete(new SearchDto(interFace.getId()));
		return new JsonResult(1, null);
	}

	@RequestMapping("/changeSequence.do")
	@ResponseBody
	public JsonResult changeSequence(@RequestParam String id, @RequestParam String changeId) throws MyException {
		Interface change = interfaceService.get(changeId);
		Interface model = interfaceService.get(id);
		hasPermission(cacheService.getProject(model.getProjectId()), modInter);
		hasPermission(cacheService.getProject(change.getProjectId()), modInter);

		int modelSequence = model.getSequence();

		model.setSequence(change.getSequence());
		change.setSequence(modelSequence);

		interfaceService.update(model);
		interfaceService.update(change);
		return new JsonResult(1, null);
	}

	public HttpServletResponse getResponse() {
		return response;
	}
}
